/*
 * Copyright (c) 2020. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package com.evenmo.string;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * This is Description
 * 面试题：
 * 编写一个容器，提供两个线程，一个线程添加元素，另一个线程监控元素的个数，当元素的个数达到某个数后给出提示
 *
 * @author moyongjun
 * @date 2020/01/03
 */
public class ThreadDemo_volatile_monitor_container {

    //容器集合
//   /**volatile*/  private List<Object> container=new ArrayList<>();

    volatile private List<Object> container=new ArrayList<>();




    public  void add(Object obj){
        container.add(obj);
    }
    public  int size(){
        return container.size();
    }

    public static void main(String[] args){
        //创建一个容器
        ThreadDemo_volatile_monitor_container mycontainer=new ThreadDemo_volatile_monitor_container();

        final Object lock=new Object();
        //监控元素个数线程，先启动
        new Thread(()->{

            System.out.println("====监控元素线程启动，监控那元素个数中====");

           synchronized (lock) {

               if (mycontainer.size() != 5) {
                   try {
                       lock.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }

               }

               System.out.println("元素个数是" + mycontainer.size());
               System.out.println("元素达到规定数目，" + Thread.currentThread().getName() + "结束");

               //通知其他线程
              lock.notifyAll();

           }
        },"监控线程").start();

        //模拟启动先后顺序

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //添加元素线程
        new Thread(()->{
            System.out.println("添加元素线程启动");
            synchronized (lock) {
                for (int i = 0; i < 10; i++) {
                    mycontainer.add(i);
                    System.out.println("添加的元素是" + i);

                    if (mycontainer.size() == 5) {
                        System.out.println("元素个数="+mycontainer.size()+",开始唤醒等待的线程》》》");
                        lock.notifyAll();

                        //notify不释放锁，wait释放锁，所以再wait下，再其他线程执行后再notify下这里

                        try {
                            lock.wait();
                            break;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        System.out.println("添加元素结束");
                    }


                    try {
                        //不睡的话cpu执行很快，达不到效果
//                        TimeUnit.SECONDS.sleep(1);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }


                }

            }

            System.out.println(Thread.currentThread().getName() + "结束");
        },"添加元素线程").start();


    }
}
